10   ' *** (APPA4.01) FFT/INV FFT ***

11   ' DIFFERENTIATES & INTEGRATES A FUNCTION

12 SCREEN 9, 1: COLOR 15, 1

13 CLS : PRINT : PRINT "INPUT NUMBER OF DATA POINTS AS 2^N"

14 INPUT "N = "; N

16 Q = 2 ^ N: Q1 = Q - 1: N1 = N - 1

18 Q2 = Q / 2: Q3 = Q2 - 1: Q4 = Q / 4: Q5 = Q4 - 1: Q8 = Q / 8

20 DIM C(Q), S(Q), KC(Q), KS(Q)

22 X0 = 50: Y0 = 200: XSF = 500 / Q: YSF = 1024: IOFLG = 1: DATGEN = 0

23 PI = 3.141592653589793#: P2 = 2 * PI: K1 = P2 / Q: PI2 = P2



24 '  **** TWIDDLE FACTOR TABLE GENERATION ****

26 FOR I = 0 TO Q: KC(I) = COS(K1 * I): KS(I) = SIN(K1 * I)

28 IF ABS(KC(I)) < .0000005 THEN KC(I) = 0 ' CLEAN UP TABLES

30 IF ABS(KS(I)) < .0000005 THEN KS(I) = 0

32 NEXT I

34 FOR I = 1 TO Q1: INDX = 0

36 FOR J = 0 TO N1

38 IF I AND 2 ^ J THEN INDX = INDX + 2 ^ (N1 - J)

40 NEXT J

42 IF INDX > I THEN SWAP KC(I), KC(INDX): SWAP KS(I), KS(INDX)

44 NEXT I

45 '  ****  PRINT MAIN MENU  ****

46 CLS

50 PRINT SPC(30); "MAIN MENU": PRINT : PRINT

52 PRINT SPC(5); "1 = GENERATE STEP FUNCTION & TRANSFORM": PRINT

54 PRINT SPC(5); "2 = FORWARD TRANSFORM": PRINT

56 PRINT SPC(5); "3 = DIFFERENTIATE FUNCTION": PRINT

57 PRINT SPC(5); "4 = INTEGRATE FUNCTION": PRINT

58 PRINT SPC(5); "5 = INVERSE TRANSFORM": PRINT

60 PRINT SPC(5); "6 = MODIFY SYSTEM": PRINT

62 PRINT SPC(5); "7 = EXIT": PRINT

70 PRINT SPC(10); "MAKE SELECTION :";

80 A$ = INKEY$: IF A$ = "" THEN 80

90 A = VAL(A$): ON A GOSUB 600, 160, 1100, 1200, 170, 180, 990

95 GOTO 46



100 '     ****  FFT ROUTINE  ****

106 T9 = TIMER

110   ' *** FFT ROUTINE ***

112 FOR M = 0 TO N1: QT = 2 ^ (N - M): QT1 = QT - 1

114 QT2 = QT / 2: QT3 = QT2 - 1: KT = 0

116   ' *** UNIVERSAL BUTTERFLY ***

118 FOR J = 0 TO Q1 STEP QT: KT2 = KT + 1

120 FOR I = 0 TO QT3: J1 = I + J: K = J1 + QT2

122 CTEMP = (C(J1) + C(K) * KC(KT) - K6 * S(K) * KS(KT)) / SK1

124 STEMP = (S(J1) + K6 * C(K) * KS(KT) + S(K) * KC(KT)) / SK1

126 CTEMP2 = (C(J1) + C(K) * KC(KT2) - K6 * S(K) * KS(KT2)) / SK1

128 S(K) = (S(J1) + K6 * C(K) * KS(KT2) + S(K) * KC(KT2)) / SK1

130 C(K) = CTEMP2: C(J1) = CTEMP: S(J1) = STEMP

132 NEXT I

134 KT = KT + 2: NEXT J

136 NEXT M

140 ' ***  BIT REVERSAL FOR FINAL DATA ***

142 FOR I = 1 TO Q1: INDX = 0

144 FOR J = 0 TO N1

146 IF I AND 2 ^ J THEN INDX = INDX + 2 ^ (N1 - J)

148 NEXT J

150 IF INDX > I THEN SWAP C(I), C(INDX): SWAP S(I), S(INDX)

152 NEXT I

154 GOTO 200



158   ' *** FORWARD FFT ***

160 IF DATGEN = 1 THEN K6 = -1: SK1 = 2 ELSE 166

162 CLS : HDR$ = "FREQ   F(COS)       F(SIN)       "

163 HDR$ = HDR$ + "FREQ   F(COS)       F(SIN)": PRINT : PRINT

164 GOSUB 100

165 RETURN

166 CLS : LOCATE 10, 20: PRINT "MUST GENERATE FUNCTION FIRST": PRINT

167 INPUT "ENTER TO CONTINUE"; A$

168 RETURN

  

   ' *** INVERSE TRANSFORM ***

170 SK1 = 1: K6 = 1: YSF = 64

172 CLS : HDR$ = "TIME    AMPLITUDE   NOT USED     "

174 HDR$ = HDR$ + "TIME   AMPLITUDE     NOT USED": PRINT : PRINT

176 GOSUB 100

178 RETURN



179 ' ***   MODIFY SYSTEM PARAMETERS   ***

180 CLS

182 INPUT "PRESENT DATA GRAPHICALLY? (Y/N):"; A$

184 IF A$ = "Y" OR A$ = "y" THEN IOFLG = 1 ELSE IOFLG = -1

186 RETURN



'   *****  OUTPUT DATA  *****

200 T9 = TIMER - T9

202 IF IOFLG = 1 THEN 250

206 ZSTP = 15

208 PRINT HDR$: PRINT : PRINT

210 FOR Z = 0 TO Q2 - 1

215 GOSUB 300

216 IF Z > ZSTP THEN 350 ' PRINT 1 SCREEN AT A TIME

220 NEXT Z

222 LOCATE 1, 1: PRINT : PRINT "TIME ="; T9

225 INPUT "C/R TO CONTINUE:"; A$

229 RETURN



250   ' *** PLOT OUTPUT ***

252 CLS : YPX = 0: IF K6 = -1 THEN 280

254 Y0 = 175

256 FOR I = 0 TO Q - 1

258 IF C(I) > YPX THEN YPX = C(I)

260 NEXT I

262 YSF = 100 / YPX

263 LINE (X0 + 10, Y0 - 100)-(X0, Y0 - 100)

264 LOCATE 6, 1: PRINT USING "###.##"; YPX

265 LINE (X0 - 1, 50)-(X0 - 1, 300)

266 LINE (X0, Y0)-(X0 + 500, Y0)

268 LINE (X0, Y0)-(X0, Y0)



270 FOR I = 0 TO Q - 1

272 YP = C(I)

274 IF K6 = -1 THEN YP = SQR(C(I) ^ 2 + S(I) ^ 2)

276 LINE -(X0 + XSF * I, Y0 - YSF * YP)

278 NEXT I

279 GOTO 222

280 ' ***   FIND Y SCALE FACTOR FOR FREQ DOMAIN PLOT   ***

281 Y0 = 300 ' SET Y AXIS ORIGIN

282 FOR I = 0 TO Q - 1 ' FIND LARGEST VALUE IN ARRAY

284 YP = SQR(C(I) ^ 2 + S(I) ^ 2): IF YP > YPX THEN YPX = YP

286 NEXT I

287 YSF = 200 / YPX ' SET SCALE FACTOR

288 LINE (X0 + 10, Y0 - 200)-(X0, Y0 - 200)

289 LOCATE 8, 1: PRINT USING "###.##"; YPX: GOTO 265



300 PRINT USING "###"; Z; : PRINT "   ";

310 PRINT USING "+##.#####"; C(Z); : PRINT "    ";

312 PRINT USING "+##.#####"; S(Z); : PRINT "      ";

320 PRINT USING "###"; Z + Q2; : PRINT "   ";

322 PRINT USING "+##.#####"; C(Z + Q2); : PRINT "    ";

324 PRINT USING "+##.#####"; S(Z + Q2)

330 RETURN



350   ' *** STOP WHEN SCREEN FULL ***

352 ZSTP = ZSTP + 16

354 PRINT : INPUT "C/R TO CONTINUE:"; A$

356 CLS : PRINT HDR$: PRINT : PRINT

358 GOTO 220



600   ' * SQUARE FUNCTION *

602 CLS : PRINT : PRINT

604 PRINT "PREPARING DATA INPUT - PLEASE WAIT!"

610 FOR I = 0 TO Q - 1: C(I) = 0: S(I) = 0

612 FOR J = 1 TO Q2 - 1 STEP 2

620 C(I) = C(I) + (SIN(K1 * I * J) / (J * 1))

630 NEXT J

640 C(I) = C(I) * 4 / PI ' CORRECT FOR UNIT SQUARE

650 NEXT I

652 HDR$ = "TIME    AMPLITUDE   NOT USED     "

654 HDR$ = HDR$ + "TIME   AMPLITUDE     NOT USED": PRINT : PRINT

660 K6 = 1: DATGEN = 1

662 GOSUB 202

680 GOSUB 160

690 RETURN



990 STOP: END





1100   ' *** DIFFERENTIATE FUNCTION ***

1102 IF K6 <> -1 THEN 1152 ' TEST FOR TRANSFORM DOMAIN

1110 FOR I = 0 TO Q3: KDF = I * P2 ' I = HARMONIC, PI = 3.1416...

1120 CTEMP = -KDF * S(I): S(I) = KDF * C(I): C(I) = CTEMP

1130 CTEMP = KDF * S(Q - I): S(Q - I) = -KDF * C(Q - I): C(Q - I) = CTEMP

1140 NEXT I

1150 GOTO 1250

1152 CLS : LOCATE 10, 20: PRINT "MUST BE IN TRANSFORM DOMAIN": PRINT : PRINT

1154 INPUT "ENTER TO CONTINUE"; A$

1156 RETURN





1200   ' *** INTEGRATE FUNCTION ***

1202 IF K6 <> -1 THEN 1152 ' TEST FOR XFORM DOMAIN

1210 FOR I = 1 TO Q3: KDF = I * P2 ' I = HARMONIC,PI = 3.14...

1220 CTEMP = S(I) / KDF: S(I) = -C(I) / KDF: C(I) = CTEMP

1230 CTEMP = -S(Q - I) / KDF: S(Q - I) = C(Q - I) / KDF: C(Q - I) = CTEMP

1240 NEXT I

1242 KDF = Q2

1244 S(Q2) = 0: C(Q2) = 0  ' ZERO NYQUEST AND CONSTANT TERMS

1250 CLS : HDR$ = "FREQ   F(COS)       F(SIN)       "

1252 HDR$ = HDR$ + "FREQ   F(COS)       F(SIN)": PRINT : PRINT

1254 GOTO 200





